######################################################################
#
# wt::util package
#
######################################################################

package require wt::core

namespace eval ::wt::util:: {
  namespace export md5Encode escapeRegexp objectType objectInfo winDebug
}

proc ::wt::util::escapeRegexp {str} {
  return [regsub -all {[\(\)\[\]\\\*\+\{\}\^\$\.\?\*]} $str {\\&}]
}

proc ::wt::util::previewString {str {max 200} {htmlEncode 1} {showLen 1}} {
  if {$str != ""} {
    set len [string length $str]
    set truncated 0
    if {$len > $max} {
      set truncated 1
      set str [string range $str 0 [expr $max - 1]]
    }
    if {$htmlEncode} {
      set str [regsub -all {([^\s]{60})} $str "\\1\x00"]
      set str [wt::web::htmlEncode $str]
      set str [regsub -all {\x000} $str "<br>"]
      if {$truncated} {
        append str "..."
        if {$showLen} {
          append str " <i>\[$len chars.\]</i>"
        }
      }
    } elseif {$truncated} {
      append str "..."
      if {$showLen} {
        append str " \[$len chars.\]"
      }
    }
  } else {
    set str "&nbsp;"
  }

  return $str;
}

proc ::wt::util::callVirtualProc {namespace command args} {
  if {$namespace == "self"} {
    set namespace [uplevel [list namespace current]]
  }

  while {1} {
    if {[info commands "${namespace}::${command}"] != ""} {
      return [uplevel [list eval [list [list "${namespace}::${command}"] $args]]]
    } else {
      set namespace [set "${namespace}::base"]
    }
  }
}

proc ::wt::util::readFile {path} {
  set fd [open $path]
  set buf [read $fd]
  close $fd
  return $buf
}

proc ::wt::util::tmpFile {{prefix {}} {suffix {}} {dir {}}} {
  if {$dir == ""} {
    set dir [tmpDir]
  }
  for {set t 0} {$t < 3} {incr t} {
    set str ""
    for {set i 0} {$i < 8} {incr i} {
      set n [expr int(rand() * 62)]
      append str [format %c [expr $n < 10 ? (48 + $n) : \
        ($n < 36 ? (65 + ($n - 10)) : (97 + ($n - 36)))]]
    }
    set path [file join $dir "$prefix$str$suffix"]
    if {![catch {open $path {CREAT EXCL RDWR} 0600} fd]} {
      return [list $path $fd]
    }
    if {[lindex $::errorCode 1] != "EEXIST" || \
        [lindex $::errorCode 0] != "POSIX"} {
      return -code error -errorcode $::errorCode $fd
    }
  }
  error "Failed to get temporary file path."
}

proc ::wt::util::tmpDir {} {
  set dir ""
  switch $::tcl_platform(platform) {
    unix {
      if {[info exists ::env(TMPDIR)] && $::env(TMPDIR) != ""} {
        set dir $::env(TMPDIR)
      } else {
        set dir /tmp
      }
    } macintosh {
      if {[info exists ::env(TRASH_FOLDER)] && $::env(TRASH_FOLDER) != ""} {
        set dir $::env(TRASH_FOLDER)
      }
    } windows {
      if {[info exists ::env(TEMP)] && $::env(TEMP) != ""} {
        set dir $::env(TEMP)
      }
    }
  }
  if {$dir == ""} {
    set dir [pwd]
  }
  return $dir
}

package provide wt::util 1
